﻿using FlyingCircusWebIS.Models;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data.OleDb;
using System.Linq;
using System.Web;

namespace FlyingCircusWebIS.Models
{

    public class EnderecoDAO: IEnderecoDAO
    {

        private ICidadeDAO cidadeDAO;

        public EnderecoDAO()
        {
            cidadeDAO = new CidadeDAO();
        }


        public void Adicionar(Endereco entidade, DbTransaction transacao = null)
        {
            string sqlAtualizar
                = "insert into ENDERECO (IdEndereco, IdCidade, Logradouro, Numero, Complemento, CEP) values (?, ?, ?, ?, ?, ?)";

            // Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = GerenciadorConexao.Conexao;
            comando.CommandText = sqlAtualizar;
            if (transacao != null)
                comando.Transaction = transacao as OleDbTransaction;

            OleDbParameter pIdEndereco = new OleDbParameter("IdEndereco", OleDbType.Integer);
            pIdEndereco.Value = entidade.IdEndereco;
            comando.Parameters.Add(pIdEndereco);

            OleDbParameter pIdCidade = new OleDbParameter("IdCidade", OleDbType.Integer);
            pIdCidade.Value = entidade.IdCidade;
            comando.Parameters.Add(pIdCidade);

            OleDbParameter pLogradouro = new OleDbParameter("Logradouro", OleDbType.VarChar);
            pLogradouro.Value = entidade.Logradouro;
            comando.Parameters.Add(pLogradouro);

            OleDbParameter pNumero = new OleDbParameter("Numero", OleDbType.VarChar);
            pNumero.Value = entidade.Numero;
            comando.Parameters.Add(pNumero);

            OleDbParameter pComplemento = new OleDbParameter("Complemento", OleDbType.VarChar);
            if (String.IsNullOrEmpty(entidade.Complemento))
                pComplemento.Value = DBNull.Value;
            else
                pComplemento.Value = entidade.Complemento;
            comando.Parameters.Add(pComplemento);

            OleDbParameter pCEP = new OleDbParameter("CEP", OleDbType.VarChar);
            pCEP.Value = entidade.Cep;
            comando.Parameters.Add(pCEP);

            // Insert
            comando.ExecuteNonQuery();
            comando.Dispose();
        }

        public int ProximoIdEndereco(DbTransaction transacao = null)
        {
            string sqlConsultar
                = "select seqEndereco.nextval from dual";

            // Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = GerenciadorConexao.Conexao;
            comando.CommandText = sqlConsultar;
            if (transacao != null)
                comando.Transaction = transacao as OleDbTransaction;

            // Select
            OleDbDataReader dr = comando.ExecuteReader();

            if (dr.Read())
            {
                int id = Convert.ToInt32(dr["NEXTVAL"]);
                dr.Close();
                comando.Dispose();
                return id;
            }

            dr.Close();
            comando.Dispose();
            throw new Exception("Erro ao recuperar o próximo ID de endereço.");

        }

        public void Atualizar(Endereco entidade, DbTransaction transacao = null)
        {
            string sqlAtualizar
                = "update ENDERECO set IdCidade = ?, Logradouro = ?, Numero = ?, Complemento = ?, CEP = ? where IdEndereco = ?";

            // Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = GerenciadorConexao.Conexao;
            comando.CommandText = sqlAtualizar;
            if (transacao != null)
                comando.Transaction = transacao as OleDbTransaction;


            OleDbParameter pIdCidade = new OleDbParameter("IdCidade", OleDbType.Integer);
            pIdCidade.Value = entidade.IdCidade;
            comando.Parameters.Add(pIdCidade);

            OleDbParameter pLogradouro = new OleDbParameter("Logradouro", OleDbType.VarChar);
            pLogradouro.Value = entidade.Logradouro;
            comando.Parameters.Add(pLogradouro);

            OleDbParameter pNumero = new OleDbParameter("Numero", OleDbType.VarChar);
            pNumero.Value = entidade.Numero;
            comando.Parameters.Add(pNumero);

            OleDbParameter pComplemento = new OleDbParameter("Complemento", OleDbType.VarChar);
            if (String.IsNullOrEmpty(entidade.Complemento))
                pComplemento.Value = DBNull.Value;
            else
                pComplemento.Value = entidade.Complemento;
            comando.Parameters.Add(pComplemento);

            OleDbParameter pCEP = new OleDbParameter("CEP", OleDbType.VarChar);
            pCEP.Value = entidade.Cep;
            comando.Parameters.Add(pCEP);

            OleDbParameter pIdEndereco = new OleDbParameter("IdEndereco", OleDbType.Integer);
            pIdEndereco.Value = entidade.IdEndereco;
            comando.Parameters.Add(pIdEndereco);

            // Update
            comando.ExecuteNonQuery();
            comando.Dispose();
        }

        public void RemoverPorId(int id, DbTransaction transacao)
        {
            string sqlDeletar = "delete ENDERECO where IdEndereco = ?";

            // Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = GerenciadorConexao.Conexao;
            comando.CommandText = sqlDeletar;
            if (transacao != null)
                comando.Transaction = transacao as OleDbTransaction;

            OleDbParameter pId = new OleDbParameter("IdEndereco", OleDbType.VarChar);
            pId.Value = id;
            comando.Parameters.Add(pId);

            // Delete
            comando.ExecuteNonQuery();
            comando.Dispose();
        }

        public Endereco BuscarPorId(int id)
        {
            Endereco registro = null;
            string sqlBuscar = "select * from ENDERECO where IdEndereco = ?";

            // Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = GerenciadorConexao.Conexao;
            comando.CommandText = sqlBuscar;

            OleDbParameter pId = new OleDbParameter("IdEndereco", OleDbType.Integer);
            pId.Value = id;
            comando.Parameters.Add(pId);

            // Select
            OleDbDataReader dr = comando.ExecuteReader();
            if (dr.Read())
            {
                registro = ConverterDataReaderParaObj(dr);
            }
            dr.Close();
            comando.Dispose();

            if (registro != null)
                CarregarComposicao(registro);

            return registro;
        }

        private void CarregarComposicao(Endereco registro)
        {
            int idCidade = registro.IdCidade;
            Cidade cidade = cidadeDAO.BuscarPorId(idCidade);
            registro.Cidade = cidade;
        }

        private Endereco ConverterDataReaderParaObj(OleDbDataReader dr)
        {
            Endereco endereco = new Endereco();
            endereco.IdEndereco = Int32.Parse(dr["IdEndereco"].ToString());
            endereco.IdCidade = Int32.Parse(dr["IdCidade"].ToString());
            endereco.Logradouro = dr["Logradouro"].ToString();
            endereco.Numero = dr["Numero"].ToString();
            endereco.Complemento = dr["Complemento"].ToString();
            endereco.Cep = dr["CEP"].ToString();

            return endereco;
        }

        public List<Endereco> Listar()
        {
            String sqlConsulta = "select * from ENDERECO";

            // Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = GerenciadorConexao.Conexao;
            comando.CommandText = sqlConsulta;

            // Select
            OleDbDataReader dr = comando.ExecuteReader();

            List<Endereco> registros = new List<Endereco>();
            while (dr.Read())
            {
                Endereco registro = ConverterDataReaderParaObj(dr);
                registros.Add(registro);
            }
            dr.Close();
            comando.Dispose();

            foreach (var registro in registros)
            {
                CarregarComposicao(registro);
            }

            return registros;
        }
    }
}